package cn.langpy.simforkjoin.core;

import cn.langpy.simforkjoin.annotation.ForkJoin;
import org.aspectj.lang.ProceedingJoinPoint;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;
import java.util.logging.Logger;

@Component
public class ContextTask {
    public static Logger log = Logger.getLogger(ContextTask.class.toString());

    ThreadLocal<Boolean> paramThreadPool = new ThreadLocal();
    @Autowired
    ApplicationContext applicationContext;

    public int execute(CompletionService executor, ProceedingJoinPoint joinPoint, Object[] args, int threshold) {
        List arg = (List) args[0];
        int len = arg.size();
        int n = len / threshold;
        log.info("数据总量为："+len+" 拆分为："+n+" 个线程计算");
        for (int i = 0; i < n; i++) {
            int start = threshold * i;
            int end = i == n - 1 ? len : start + threshold;
            executor.submit(new CutTask(joinPoint, args, start, end));
        }
        return n;
    }

    public boolean validate(ForkJoin forkJoin, Object[] args) {
        if (args == null || args.length == 0) {
            throw new RuntimeException("@ForkJoin修饰的方法要求至少一个不为空的参数，且第一个参数类型为List");
        }
        if (!(args[0] instanceof List)) {
            throw new RuntimeException("@ForkJoin修饰的方法的第一个参数类型必须为List，且不能为空");
        }
        if (forkJoin.threshold() <= 0) {
            throw new RuntimeException("@ForkJoin的threshold必须为正整数");

        }
        return true;
    }

    public ExecutorService getExecutor(ForkJoin forkJoin) {
        ExecutorService asyncTaskExecutor = null;
        if (forkJoin.executor() != null && forkJoin.executor().length() > 0) {
            Object e = applicationContext.getBean(forkJoin.executor());
            if (e!=null && e instanceof ExecutorService) {
                asyncTaskExecutor = (ExecutorService) e;
                paramThreadPool.set(Boolean.TRUE);
            }else{
                throw new RuntimeException("@ForkJoin仅支持ExecutorService类型的线程池");
            }
        }else{
            asyncTaskExecutor = ForkJoinPool.commonPool();
            paramThreadPool.set(Boolean.FALSE);
        }
        return asyncTaskExecutor;
    }

    public void closeThreadPool(ExecutorService threadExecutor) {
        if (paramThreadPool.get()==false) {
            threadExecutor.shutdown();
            paramThreadPool.remove();
        }
    }


}
